[NET]: Fix segmentation of linear packets
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Fri, 15 Dec 2006 09:38:56 +0000 (09:38 +0000)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Fri, 15 Dec 2006 09:38:56 +0000 (09:38 +0000)
skb_segment fails to segment linear packets correctly because it
tries to write all linear parts of the original skb into each
segment.  This will always panic as each segment only contains
enough space for one MSS.

This was not detected earlier because linear packets should be
rare for GSO.  In fact it still remains to be seen what exactly
created the linear packets that triggered this bug.  Basically
the only time this should happen is if someone enables GSO
emulation on an interface that does not support SG.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
linux-2.6-xen-sparse/net/core/skbuff.c
patches/linux-2.6.16.33/net-gso-6-linear-segmentation.patch [new file with mode: 0644]
patches/linux-2.6.16.33/series

index 064e6277b1382dcc349b8b06415a22074654c55c..5a524946b0f678b7428a57a407a1ccfd0dc5656f 100644 (file)
@@ -1875,7 +1875,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
        do {
                struct sk_buff *nskb;
                skb_frag_t *frag;
-               int hsize, nsize;
+               int hsize;
                int k;
                int size;
 
@@ -1886,11 +1886,10 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
                hsize = skb_headlen(skb) - offset;
                if (hsize < 0)
                        hsize = 0;
-               nsize = hsize + doffset;
-               if (nsize > len + doffset || !sg)
-                       nsize = len + doffset;
+               if (hsize > len || !sg)
+                       hsize = len;
 
-               nskb = alloc_skb(nsize + headroom, GFP_ATOMIC);
+               nskb = alloc_skb(hsize + doffset + headroom, GFP_ATOMIC);
                if (unlikely(!nskb))
                        goto err;
 
diff --git a/patches/linux-2.6.16.33/net-gso-6-linear-segmentation.patch b/patches/linux-2.6.16.33/net-gso-6-linear-segmentation.patch
new file mode 100644 (file)
index 0000000..5e615a1
--- /dev/null
@@ -0,0 +1,26 @@
+diff -Naru a/net/core/skbuff.c b/net/core/skbuff.c
+--- a/net/core/skbuff.c        2006-12-14 09:32:04 -08:00
++++ b/net/core/skbuff.c        2006-12-14 09:32:04 -08:00
+@@ -1946,7 +1946,7 @@
+       do {
+               struct sk_buff *nskb;
+               skb_frag_t *frag;
+-              int hsize, nsize;
++              int hsize;
+               int k;
+               int size;
+@@ -1957,11 +1957,10 @@
+               hsize = skb_headlen(skb) - offset;
+               if (hsize < 0)
+                       hsize = 0;
+-              nsize = hsize + doffset;
+-              if (nsize > len + doffset || !sg)
+-                      nsize = len + doffset;
++              if (hsize > len || !sg)
++                      hsize = len;
+-              nskb = alloc_skb(nsize + headroom, GFP_ATOMIC);
++              nskb = alloc_skb(hsize + doffset + headroom, GFP_ATOMIC);
+               if (unlikely(!nskb))
+                       goto err;
index 28fabf00ff134dd7875d447d7add0f118623b181..8410fb3bde6c0527aa21f0961d3e93df809dea27 100644 (file)
@@ -17,6 +17,7 @@ net-gso-2-checksum-fix.patch
 net-gso-3-fix-errorcheck.patch
 net-gso-4-kill-warnon.patch
 net-gso-5-rcv-mss.patch
+net-gso-6-linear-segmentation.patch
 pci-mmconfig-fix-from-2.6.17.patch
 pmd-shared.patch
 rcu_needs_cpu.patch